package org.jeecg.glr.util;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jeecg.glr.domain.led.DataDomain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;

public class HttpRequestUtil
{
	private static final Logger log = LoggerFactory.getLogger(HttpRequestUtil.class);
	private static final String nextLine = "\r\n";
	private static final String twoHyphens = "--";
	//分割线  随便写一个
	private static final String boundary = "wk_file_2519775";
    public static final String PHP_GETSINGLETERMINALDATA_URL="http://106.14.140.133:8999/php/getsingleterminaldata.php";


    public static final String PHP_ADDTASKINFO_URL="http://106.14.140.133:8999/php/addtaskinfo.php";

    public static final String  PHP_MODIFYTASKINFO_URL="http://106.14.140.133:8999/php/modifytaskinfo.php";

    public static final String  PHP_EXETASKCMD_URL="http://106.14.140.133:8999/php/exetaskcmd.php";


    /**
     * 世邦上传资源
     */
    public static final String PHP_ADDMEDIADATA_URL="http://106.14.140.133:8999/php/addmediadata.php";
    /**
     * 世邦删除资源
     */
    public static final String PHP_DELMEDIADATA_URL="http://106.14.140.133:8999/php/delmediadata.php";

	/**
	 * GET方法提交
	 */
	public static final String GET = "GET";

	/**
	 * POST方法提交
	 */
	public static final String POST = "POST";

	/**
	 * 百度地图经纬度转换
	 */
	public static final String BAI_DU_GEOCONV_URL = "http://api.map.baidu.com/geoconv/v1/?coords=LATLNG&from=1&to=5&ak=G4ZL5QDQzacEbVlbXpXjutS9LQSIScDQ";

	/**
	 * 根据appKey和secret获取accessToken
	 */
	public static final String YS_TOKEN_URL = "https://open.ys7.com/api/lapp/token/get?appKey=APPKEY&appSecret=APPSECRET";

	/**
	 * 根据appKey和secret获取accessToken
	 */
	public static final String BAIDU_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&&client_id=APPKEY&client_secret=APPSECRET";
	public static final String BAIDU_USER_ADD_URL = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";
	public static final String BAIDU_USER_GROUP_ID ="glr20190912";
	public static final String BAIDU_USER_FACE_SEARCH = "https://aip.baidubce.com/rest/2.0/face/v3/search";
	public static final String BAIDU_FACE_DETECT = "https://aip.baidubce.com/rest/2.0/face/v3/detect";
	/**
	 * 
	 */
	public static final String YS_ADDRESS_URL = "https://open.ys7.com/api/lapp/live/address/get?accessToken=ACCESSTOKEN&source=SOURCE";
	/**
	 * 获取单个设备信息
	 */
	public static final String YS_DEVICE_INFO_URL = "https://open.ys7.com/api/lapp/device/info?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL";
    /**
     * 获取设备列表
     */
    public static final String YS_DEVICE_LIST_URL = "https://open.ys7.com/api/lapp/device/list?accessToken=ACCESSTOKEN&pageStart=PAGESTART&pageSize=PAGESIZE";
	/**
	 * 获取客流统计开关状态
	 */
	public static final String YS_DEVICE_PASSENGER_FLOW_SWITCH_STATUS = "https://open.ys7.com/api/lapp/passengerflow/switch/status?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL";
	/**
	 * 设置客流统计开关
	 */
	public static final String YS_DEVICE_PASSENGER_FLOW_SWITCH_SET = "https://open.ys7.com/api/lapp/passengerflow/switch/set?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&enable=ENABLE&channelNo=CHANNELNO";
	/**
	 * 查询设备某一天的统计客流数据
	 */
	public static final String YS_DEVICE_PASSENGER_FLOW_DAILY = "https://open.ys7.com/api/lapp/passengerflow/daily?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&date=DATE";
	/**
	 * 查询设备某一天每小时的客流数据
	 */
	public static final String YS_DEVICE_PASSENGER_FLOW_HOURLY = "https://open.ys7.com/api/lapp/passengerflow/hourly?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&date=DATE";
	/**
	 * 配置客流统计信息
	 */
	public static final String YS_DEVICE_PASSENGER_CONFIG_SET = "https://open.ys7.com/api/lapp/passengerflow/config/set?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&line=LINE&direction=DIRECTION";
	/**
	 * 获取客流统计配置信息
	 */
	public static final String YS_DEVICE_PASSENGER_CONFIG_GET = "https://open.ys7.com/api/lapp/passengerflow/config/get?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO";
	/**
	 * 开始云台控制
	 */
	public static final String YS_DEVICE_START_URL = "https://open.ys7.com/api/lapp/device/ptz/start?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&direction=DIRECTION&speed=SPEED";

	/**
	 * 停止云台控制
	 */
	public static final String YS_DEVICE_STOP_URL = "https://open.ys7.com/api/lapp/device/ptz/stop?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO";

	/**
	 * 镜像翻转
	 */
	public static final String YS_DEVICE_MIRROR_URL = "https://open.ys7.com/api/lapp/device/ptz/mirror?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&command=COMMAND";

	/**
	 * 获取单个设备信息
	 */
	public static final String YS_DEVICE_LIVE_ADDRESS_URL = "https://open.ys7.com/api/lapp/live/address/get?accessToken=ACCESSTOKEN&source=SOURCE";

    /**
     * 关闭设备视频加密
     */
    public static final String YS_DEVICE_ENRYPT_URL = "https://open.ys7.com/api/lapp/device/encrypt/off?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&validateCode=VALIDATECODE";


	/**
	 * 添加预置点
	 */
	public static final String YS_DEVICE_PRESET_ADD_URL = "https://open.ys7.com/api/lapp/device/preset/add?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO";

	/**
	 * 调用预置点
	 */
	public static final String YS_DEVICE_PRESET_MOVE_URL = "https://open.ys7.com/api/lapp/device/preset/move?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&index=INDEX";

	/**
	 * 清除预置点
	 */
	public static final String YS_DEVICE_PRESET_CLEAR_URL = "https://open.ys7.com/api/lapp/device/preset/clear?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO&index=INDEX";

	/**
	 * 设备抓拍图片
	 */
	public static final String YS_DEVICE_CAPTURE_URL = "https://open.ys7.com/api/lapp/device/capture?accessToken=ACCESSTOKEN&deviceSerial=DEVICESERIAL&channelNo=CHANNELNO";


	/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr)
	{
		//System.out.println("httpRequest" + requestUrl);
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try
		{
			// 建立连接
			URL url = new URL(requestUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setRequestMethod(requestMethod);
			if("GET".equalsIgnoreCase(requestMethod))
			{
				connection.connect();
			}

			// 当有数据需要提交时
			if(null != outputStr)
			{
				OutputStream outputStream = connection.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 流处理
			InputStream input = connection.getInputStream();
			InputStreamReader inputReader = new InputStreamReader(input, "UTF-8");
			BufferedReader reader = new BufferedReader(inputReader);
			String line;
			while ((line = reader.readLine()) != null)
			{
				buffer.append(line);
			}
			// 关闭连接、释放资源
			reader.close();
			inputReader.close();
			input.close();
			input = null;
			connection.disconnect();
			ObjectMapper objectMapper = new ObjectMapper();
			jsonObject = objectMapper.readValue(buffer.toString(), JSONObject.class);
		}
		catch (Exception e)
		{
			log.error("ERROR:", e);
			e.printStackTrace();
		}
		return jsonObject;
	}

	/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpRequestResultAjaxJson(String requestUrl, String requestMethod,
			String outputStr)
	{
		 log.info("请求的URL地址:[{}]",requestUrl);
		StringBuffer buffer = new StringBuffer();
        JSONObject jsonObject = null;
		try
		{
			// 建立连接
			URL url = new URL(requestUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setRequestMethod(requestMethod);
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            // 传输的类型
			if("GET".equalsIgnoreCase(requestMethod))
			{
				connection.connect();
			}

			// 当有数据需要提交时
			if(null != outputStr)
			{
				OutputStream outputStream = connection.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 流处理
			InputStream input = connection.getInputStream();
			InputStreamReader inputReader = new InputStreamReader(input, "UTF-8");
			BufferedReader reader = new BufferedReader(inputReader);
			String line;
			while ((line = reader.readLine()) != null)
			{
				buffer.append(line);
			}
			// 关闭连接、释放资源
			reader.close();
			inputReader.close();
			input.close();
			input = null;
			connection.disconnect();
            ObjectMapper objectMapper = new ObjectMapper();
            jsonObject = objectMapper.readValue(buffer.toString(), JSONObject.class);
		return jsonObject;
		}
		catch (Exception e)
		{
			log.error("ERROR:", e);
			e.printStackTrace();
		}
		return jsonObject;
	}




    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl
     *            请求地址
     * @param requestMethod
     *            请求方式（GET、POST）
     * @param outputStr
     *            提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static ResponseMessage<DataDomain> httpRequestResultAjaxJsonDataDoamin(String requestUrl, String requestMethod,
                                                                                  String outputStr)
    {

        log.info("请求的URL地址:[{}]",requestUrl);
        ResponseMessage<DataDomain> msg = new ResponseMessage<DataDomain>();
        StringBuffer buffer = new StringBuffer();
        try
        {
            // 建立连接
            URL url = new URL(requestUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            // 传输的类型
            if("GET".equalsIgnoreCase(requestMethod))
            {
                connection.connect();
            }

            // 当有数据需要提交时
            if(null != outputStr)
            {
                OutputStream outputStream = connection.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 流处理
            InputStream input = connection.getInputStream();
            InputStreamReader inputReader = new InputStreamReader(input, "UTF-8");
            BufferedReader reader = new BufferedReader(inputReader);
            String line;
            while ((line = reader.readLine()) != null)
            {
                buffer.append(line);
            }
            // 关闭连接、释放资源
            reader.close();
            inputReader.close();
            input.close();
            input = null;
            connection.disconnect();
            ObjectMapper objectMapper = new ObjectMapper();
            msg = objectMapper.readValue(buffer.toString(), ResponseMessage.class);
        }
        catch (Exception e)
        {
            log.error("ERROR:", e);
            e.printStackTrace();
        }
        return msg;
    }


	/*** 上传图片 
     * @param urlStr 
     * @param fileMap
     * @return 
     */  
    public static JSONObject formUpload(String urlStr, String outputStr, Map<String, String> fileMap) {  
        JSONObject jsonObject = null;
        HttpURLConnection conn = null;  
        try {
            URL url = new URL(urlStr);  
            conn = (HttpURLConnection) url.openConnection();  
            conn.setConnectTimeout(5000);  
            conn.setReadTimeout(30000);  
            conn.setDoOutput(true);  
            conn.setDoInput(true);  
            conn.setUseCaches(false);  
            conn.setRequestMethod("POST");  
            conn.setRequestProperty("Connection", "Keep-Alive");  
            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");  
            conn.setRequestProperty("Content-Type", "multipart/form-data; ");
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            // text    
            if(null != outputStr) {
            	/*
                StringBuffer strBuf = new StringBuffer();  
                Iterator<Map.Entry<String, String>> iter = textMap.entrySet().iterator();  
                while (iter.hasNext()) {  
                    Map.Entry<String, String> entry = iter.next();  
                    String inputName = (String) entry.getKey();  
                    String inputValue = (String) entry.getValue();  
                    if (inputValue == null) {  
                        continue;  
                    }  
                    strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");  
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");  
                    strBuf.append(inputValue);  
                }  
                out.write(strBuf.toString().getBytes());  
                */
            	StringBuffer strBuf = new StringBuffer();  
                strBuf.append("Content-Disposition: form-data; " + outputStr);
                // 注意编码格式，防止中文乱码
                out.write(outputStr.getBytes("UTF-8"));
            }  
  
            // file    
            if (fileMap != null) {  
                Iterator<Map.Entry<String, String>> iter = fileMap.entrySet().iterator();  
                while (iter.hasNext()) {  
                    Map.Entry<String, String> entry = iter.next();  
                    String inputName = (String) entry.getKey();  
                    String inputValue = (String) entry.getValue();  
                    if (inputValue == null) {  
                        continue;  
                    }  
                    File file = new File(inputValue);  
                    String filename = file.getName();  
                    //MagicMatch match = Magic.getMagicMatch(file, false, true);  
                    //String contentType = match.getMimeType();  
                    String contentType = "application/octet-stream";
                    
                    StringBuffer strBuf = new StringBuffer();  
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n");
                    strBuf.append("Content-Type:" + contentType + "\r\n\r\n");  
  
                    out.write(strBuf.toString().getBytes());  

                    DataInputStream in = new DataInputStream(new FileInputStream(file));
                    int bytes = 0;  
                    byte[] bufferOut = new byte[1024];  
                    while ((bytes = in.read(bufferOut)) != -1) {  
                        out.write(bufferOut, 0, bytes);  
                    }
                    in.close();  
                }
            }  
  
            out.flush();
            out.close();  
  
            // 读取返回数据    
            StringBuffer strBuf = new StringBuffer();  
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));  
            String line = null;  
            while ((line = reader.readLine()) != null) {  
                strBuf.append(line).append("\n");  
            }  
            ObjectMapper objectMapper = new ObjectMapper();
			jsonObject = objectMapper.readValue(strBuf.toString(), JSONObject.class);
            reader.close();  
            reader = null;  
        } catch (Exception e) {  
            //System.out.println("发送POST请求出错。" + urlStr);
            e.printStackTrace();  
        } finally {  
            if (conn != null) {  
                conn.disconnect();  
                conn = null;  
            }  
        }  
        return jsonObject;
    }


	private static HttpURLConnection createConnection(String urlPath, String method) throws IOException {
		URL url = new URL(urlPath);
		HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
		httpURLConnection.setRequestMethod(method);

		httpURLConnection.setRequestProperty("Charsert", "UTF-8");
		return httpURLConnection;
	}
    /**
     * @param url 请求地址
     * @param map 请求的参数
     * @param body_data 上传的文件二进制内容
     * @param charset 字符集
     * @return
     */
    public static JSONObject doPostSubmitBody(String url, Map<String, String> map,
                                              String fileName, byte[] body_data, String charset) {
        JSONObject jsonObject = null;
        // 设置三个常用字符串常量：换行、前缀、分界线（NEWLINE、PREFIX、BOUNDARY）；
        final String NEWLINE = "\r\n"; // 换行，或者说是回车
        final String PREFIX = "--"; // 固定的前缀
        final String BOUNDARY = "#"; // 分界线，就是上面提到的boundary，可以是任意字符串，建议写长一点，这里简单的写了一个#
        HttpURLConnection httpConn = null;
        BufferedInputStream bis = null;
        DataOutputStream dos = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // 实例化URL对象。调用URL有参构造方法，参数是一个url地址；
            URL urlObj = new URL(url);
            // 调用URL对象的openConnection()方法，创建HttpURLConnection对象；
            httpConn = (HttpURLConnection) urlObj.openConnection();
            // 调用HttpURLConnection对象setDoOutput(true)、setDoInput(true)、setRequestMethod("POST")；
            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            httpConn.setRequestMethod("POST");
            // 设置Http请求头信息；（Accept、Connection、Accept-Encoding、Cache-Control、Content-Type、User-Agent），不重要的就不解释了，直接参考抓包的结果设置即可
            httpConn.setUseCaches(false);
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("Accept", "*/*");
            httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate");
            httpConn.setRequestProperty("Cache-Control", "no-cache");
            // 这个比较重要，按照上面分析的拼装出Content-Type头的内容
            httpConn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + BOUNDARY);
            // 这个参数可以参考浏览器中抓出来的内容写，用chrome或者Fiddler抓吧看看就行
            httpConn.setRequestProperty(
                    "User-Agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)");
            // 调用HttpURLConnection对象的connect()方法，建立与服务器的真实连接；
            httpConn.connect();

            // 调用HttpURLConnection对象的getOutputStream()方法构建输出流对象；
            dos = new DataOutputStream(httpConn.getOutputStream());
            // 获取表单中上传控件之外的控件数据，写入到输出流对象（根据上面分析的抓包的内容格式拼凑字符串）；
            if (map != null && !map.isEmpty()) { // 这时请求中的普通参数，键值对类型的，相当于上面分析的请求中的username，可能有多个
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    String key = entry.getKey(); // 键，相当于上面分析的请求中的username
                    String value = map.get(key); // 值，相当于上面分析的请求中的sdafdsa
                    dos.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线，就是前缀+分界线+换行
                    dos.writeBytes("Content-Disposition: form-data; "
                            + "name=\"" + key + "\"" + NEWLINE); // 拼接参数名，格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键，别忘了最后的换行
                    dos.writeBytes(NEWLINE); // 空行，一定不能少，键和值之间有一个固定的空行
                   // dos.writeBytes(URLEncoder.encode(value.toString(), charset)); // 将值写入
                    dos.write(value.getBytes(charset));
                    // 或者写成：dos.write(value.toString().getBytes(charset));
                    dos.writeBytes(NEWLINE); // 换行
                } // 所有循环完毕，就把所有的键值对都写入了
            }

            // 获取表单中上传附件的数据，写入到输出流对象（根据上面分析的抓包的内容格式拼凑字符串）；
            if (body_data != null && body_data.length > 0) {
                dos.writeBytes(PREFIX + BOUNDARY + NEWLINE);// 像请求体中写分割线，就是前缀+分界线+换行
                // 格式是:Content-Disposition: form-data; name="请求参数名"; filename="文件名"
                // 我这里吧请求的参数名写成了uploadFile，是死的，实际应用要根据自己的情况修改
                // 不要忘了换行
                fileName = new String(fileName.getBytes("utf-8"),"ISO-8859-1");
                dos.writeBytes("Content-Disposition: form-data; name=file; filename="+fileName + NEWLINE);


                // 换行，重要！！不要忘了
                dos.writeBytes(NEWLINE);
                dos.write(body_data); // 上传文件的内容
                dos.writeBytes(NEWLINE); // 最后换行
            }
            dos.writeBytes(PREFIX + BOUNDARY + PREFIX + NEWLINE); // 最后的分割线，与前面的有点不一样是前缀+分界线+前缀+换行，最后多了一个前缀
            dos.flush();

            // 调用HttpURLConnection对象的getInputStream()方法构建输入流对象；
            byte[] buffer = new byte[8 * 1024];
            int c = 0;
            // 调用HttpURLConnection对象的getResponseCode()获取客户端与服务器端的连接状态码。如果是200，则执行以下操作，否则返回null；
            if (httpConn.getResponseCode() == 200) {
                bis = new BufferedInputStream(httpConn.getInputStream());
                while ((c = bis.read(buffer)) != -1) {
                    baos.write(buffer, 0, c);
                    baos.flush();
                }
            }
            // 将输入流转成字节数组，返回给客户端。
            ObjectMapper objectMapper = new ObjectMapper();
            jsonObject = objectMapper.readValue(new String(baos.toByteArray(), charset), JSONObject.class);
            return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (dos != null)
                    dos.close();
                if (bis != null)
                    bis.close();
                if (baos != null)
                    baos.close();
                httpConn.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     * @param url 请求地址
     * @param map 请求的参数
     * @param charset 字符集
     * @return
     */
    public static JSONObject doPost(String url, Map<String, String> map,String charset) {
        JSONObject jsonObject = null;
        // 设置三个常用字符串常量：换行、前缀、分界线（NEWLINE、PREFIX、BOUNDARY）；
        final String NEWLINE = "\r\n"; // 换行，或者说是回车
        final String PREFIX = "--"; // 固定的前缀
        final String BOUNDARY = "#"; // 分界线，就是上面提到的boundary，可以是任意字符串，建议写长一点，这里简单的写了一个#
        HttpURLConnection httpConn = null;
        BufferedInputStream bis = null;
        DataOutputStream dos = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // 实例化URL对象。调用URL有参构造方法，参数是一个url地址；
            URL urlObj = new URL(url);
            // 调用URL对象的openConnection()方法，创建HttpURLConnection对象；
            httpConn = (HttpURLConnection) urlObj.openConnection();
            // 调用HttpURLConnection对象setDoOutput(true)、setDoInput(true)、setRequestMethod("POST")；
            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            httpConn.setRequestMethod("POST");
            // 设置Http请求头信息；（Accept、Connection、Accept-Encoding、Cache-Control、Content-Type、User-Agent），不重要的就不解释了，直接参考抓包的结果设置即可
            httpConn.setUseCaches(false);
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("Accept", "*/*");
            httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate");
            httpConn.setRequestProperty("Cache-Control", "no-cache");
            // 这个比较重要，按照上面分析的拼装出Content-Type头的内容
            httpConn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + BOUNDARY);
            // 这个参数可以参考浏览器中抓出来的内容写，用chrome或者Fiddler抓吧看看就行
            httpConn.setRequestProperty(
                    "User-Agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)");
            // 调用HttpURLConnection对象的connect()方法，建立与服务器的真实连接；
            httpConn.connect();

            // 调用HttpURLConnection对象的getOutputStream()方法构建输出流对象；
            dos = new DataOutputStream(httpConn.getOutputStream());
            // 获取表单中上传控件之外的控件数据，写入到输出流对象（根据上面分析的抓包的内容格式拼凑字符串）；
            if (map != null && !map.isEmpty()) { // 这时请求中的普通参数，键值对类型的，相当于上面分析的请求中的username，可能有多个
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    String key = entry.getKey(); // 键，相当于上面分析的请求中的username
                    String value = map.get(key); // 值，相当于上面分析的请求中的sdafdsa
                    dos.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线，就是前缀+分界线+换行
                    dos.writeBytes("Content-Disposition: form-data; "
                            + "name=\"" + key + "\"" + NEWLINE); // 拼接参数名，格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键，别忘了最后的换行
                    dos.writeBytes(NEWLINE); // 空行，一定不能少，键和值之间有一个固定的空行
                    //  dos.writeBytes(URLEncoder.encode(value.toString(), charset)); // 将值写入
                    dos.write(value.getBytes(charset));
                    // 或者写成：dos.write(value.toString().getBytes(charset));
                    dos.writeBytes(NEWLINE); // 换行
                } // 所有循环完毕，就把所有的键值对都写入了
            }
            dos.writeBytes(PREFIX + BOUNDARY + PREFIX + NEWLINE); // 最后的分割线，与前面的有点不一样是前缀+分界线+前缀+换行，最后多了一个前缀
            dos.flush();

            // 调用HttpURLConnection对象的getInputStream()方法构建输入流对象；
            byte[] buffer = new byte[8 * 1024];
            int c = 0;
            // 调用HttpURLConnection对象的getResponseCode()获取客户端与服务器端的连接状态码。如果是200，则执行以下操作，否则返回null；
            if (httpConn.getResponseCode() == 200) {
                bis = new BufferedInputStream(httpConn.getInputStream());
                while ((c = bis.read(buffer)) != -1) {
                    baos.write(buffer, 0, c);
                    baos.flush();
                }
            }
            // 将输入流转成字节数组，返回给客户端。
            ObjectMapper objectMapper = new ObjectMapper();
            jsonObject = objectMapper.readValue(new String(baos.toByteArray(), charset), JSONObject.class);
            return jsonObject;
        } catch (Exception e) {
            //System.out.println("连接打-------3333--------不开!");
            e.printStackTrace();
        } finally {
            try {
                if (dos != null)
                    dos.close();
                if (bis != null)
                    bis.close();
                if (baos != null)
                    baos.close();
                httpConn.disconnect();
            } catch (Exception e) {
                //System.out.println("连接打-------111-----------不开!");
              //  e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * @param url 请求地址
     * @param map 请求的参数
     * @param charset 字符集
     * @return
     */
    public static String doPostReturn(String url, Map<String, String> map,String charset) {
        JSONObject jsonObject = null;
        // 设置三个常用字符串常量：换行、前缀、分界线（NEWLINE、PREFIX、BOUNDARY）；
        final String NEWLINE = "\r\n"; // 换行，或者说是回车
        final String PREFIX = "--"; // 固定的前缀
        final String BOUNDARY = "#"; // 分界线，就是上面提到的boundary，可以是任意字符串，建议写长一点，这里简单的写了一个#
        HttpURLConnection httpConn = null;
        BufferedInputStream bis = null;
        DataOutputStream dos = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // 实例化URL对象。调用URL有参构造方法，参数是一个url地址；
            URL urlObj = new URL(url);
            // 调用URL对象的openConnection()方法，创建HttpURLConnection对象；
            httpConn = (HttpURLConnection) urlObj.openConnection();
            // 调用HttpURLConnection对象setDoOutput(true)、setDoInput(true)、setRequestMethod("POST")；
            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            httpConn.setRequestMethod("POST");
            // 设置Http请求头信息；（Accept、Connection、Accept-Encoding、Cache-Control、Content-Type、User-Agent），不重要的就不解释了，直接参考抓包的结果设置即可
            httpConn.setUseCaches(false);
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("Accept", "*/*");
            httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate");
            httpConn.setRequestProperty("Cache-Control", "no-cache");
            // 这个比较重要，按照上面分析的拼装出Content-Type头的内容
            httpConn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + BOUNDARY);
            // 这个参数可以参考浏览器中抓出来的内容写，用chrome或者Fiddler抓吧看看就行
            httpConn.setRequestProperty(
                    "User-Agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)");
            // 调用HttpURLConnection对象的connect()方法，建立与服务器的真实连接；
            httpConn.connect();

            // 调用HttpURLConnection对象的getOutputStream()方法构建输出流对象；
            dos = new DataOutputStream(httpConn.getOutputStream());
            // 获取表单中上传控件之外的控件数据，写入到输出流对象（根据上面分析的抓包的内容格式拼凑字符串）；
            if (map != null && !map.isEmpty()) { // 这时请求中的普通参数，键值对类型的，相当于上面分析的请求中的username，可能有多个
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    String key = entry.getKey(); // 键，相当于上面分析的请求中的username
                    String value = map.get(key); // 值，相当于上面分析的请求中的sdafdsa
                    dos.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线，就是前缀+分界线+换行
                    dos.writeBytes("Content-Disposition: form-data; " + "name=\"" + key + "\"" + NEWLINE); // 拼接参数名，格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键，别忘了最后的换行
                    dos.writeBytes(NEWLINE); // 空行，一定不能少，键和值之间有一个固定的空行
                    // dos.writeBytes(value); // 将值写入
                    dos.write(value.getBytes(charset));
                    dos.writeBytes(NEWLINE); // 换行
                } // 所有循环完毕，就把所有的键值对都写入了
            }
            dos.writeBytes(PREFIX + BOUNDARY + PREFIX + NEWLINE); // 最后的分割线，与前面的有点不一样是前缀+分界线+前缀+换行，最后多了一个前缀
            dos.flush();

            // 调用HttpURLConnection对象的getInputStream()方法构建输入流对象；
            byte[] buffer = new byte[8 * 1024];
            int c = 0;
            // 调用HttpURLConnection对象的getResponseCode()获取客户端与服务器端的连接状态码。如果是200，则执行以下操作，否则返回null；
            if (httpConn.getResponseCode() == 200) {
                bis = new BufferedInputStream(httpConn.getInputStream());
                while ((c = bis.read(buffer)) != -1) {
                    baos.write(buffer, 0, c);
                    baos.flush();
                }
            }
            // 将输入流转成字节数组，返回给客户端。
            return new String(baos.toByteArray(), charset);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (dos != null)
                    dos.close();
                if (bis != null)
                    bis.close();
                if (baos != null)
                    baos.close();
                httpConn.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }







}
